Deploy Ketty in production
Setting up required services
This guide is for deploying Ketty (v2) in production. Refer to Repositories & Setup to build Ketty (v2) or Editoria (v1) locally.
There are a few things that need to be up and running before running the app:
- Databases
- S3-compatible object storage
- Coko microservices:
- Pagedjs (pdf preview & generation)
- XSweet (docx upload to html conversions)
- EpubChecker (epub validation before generating file)
- Flax (publish books on the web)
Databases
The app, as well as each of the microservices needs a separate postgresql database to connect to. Make sure that the pgcrypto extension is installed on each of them.
To install this extension you can run CREATE EXTENSION IF NOT EXISTS pgcrypto;
in your postgres environment.
Additionally, the database for the main app needs the pgvector extension, used for RAG Search in the Knowledge Base. To install pgvector run CREATE EXTENSION IF NOT EXISTS vector;
in your postgres environment.
Object storage
An S3 or S3-compatible (eg. Minio, Google cloud, Digital ocean and more) object storage bucket is needed for file uploads.
Coko Microservices
Each of the microservices will need a client id and a client secret. These values will then be passed to Ketty's server as environment variables, so that the server can perform its authentication with the microservices. To get a valid id/secret pair, run yarn create:client
in the respective microservice.
All microservices are published in dockerhub:
- Pagedjs: https://hub.docker.com/r/cokoapps/pagedjs/tags
- Xsweet: https://hub.docker.com/r/cokoapps/xsweet/tags
- Epubchecker: https://hub.docker.com/r/cokoapps/epubchecker/tags
- Flax: https://hub.docker.com/r/cokoapps/ketty-flax/tags
For more details on how to run each microservice, check the read me file in the following repos:
- Pagedjs: https://gitlab.coko.foundation/cokoapps/pagedjs
- Xsweet: https://gitlab.coko.foundation/cokoapps/xsweet
- Epubchecker: https://gitlab.coko.foundation/cokoapps/epub-checker
- Flax: https://gitlab.coko.foundation/coko-org/products/ketty/flax
Running Ketty
Ketty is provided as two separate docker containers (Ketty client and Ketty server). The two containers will run on separate ports (or even separate machines if that suits the specific setup). The client image only serves a static bundle.
Repositories
You can find the repos for Ketty server & client in the following links:
- Ketty client: https://gitlab.coko.foundation/ketty/ketty
- Ketty server: https://gitlab.coko.foundation/ketty/server
Environment variables
First thing to do is to setup the correct environment variables in the environment where the containers will run. The most up to date list of environment variables can be found in the production compose file in the Ketty repo. You can use this compose file as is, or recreate its logic with the docker compose equivalent of your choice (eg. kubernetes).
Some notes on specific variables:
- Make sure
NODE_ENV=production
on production environments - Make sure
SERVER_SERVE_CLIENT
is set tofalse
- Make sure each container has a unique
SERVER_IDENTIFIER
value - Make sure
FEATURE_UPLOAD_DOCX_FILES
is set totrue
- Make sure
FEATURE_BOOK_STRUCTURE
is set tofalse
- Make sure
KETIDA_FLAVOUR
is set toLULU
FEATURE_POD=true
is required for v2SERVICE_ICML_...
variables are optional, as they are not used in v2- If you are not using wax's AI integration, you can skip the
AI_ENABLED
andCHAT_GPT_KEY
variables MAILER_...
variables are necessary for emails to workWS_HEARTBEAT_INTERVAL
,FAIL_SAFE_UNLOCKING_INTERVAL
,TEMP_DIRECTORY_CRON_JOB_SCHEDULE
andTEMP_DIRECTORY_CRON_JOB_OFFSET
are optional unless you want to override their values
Config file
To enable export templates and integration with lulu, you will also need to mount a config file (eg. with compose) inside the server container at the config/local.js
location.
This will enable these specific templates, but you can also replace these with the templates of your choice.
Note that in the lulu integration section, you should replace the {clientUrl}
and {luluClientId}
with proper values, as well as replace the sandbox values with their non-sandboxes equivalents.
module.exports = {
templates: [
{
label: "slategrey",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/slategrey.git",
assetsRoot: "dist",
supportedNoteTypes: ["footnotes"],
},
{
label: "significa",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/significa.git",
assetsRoot: "dist",
supportedNoteTypes: ["footnotes"],
},
{
label: "bikini",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/bikini.git",
assetsRoot: "dist",
supportedNoteTypes: ["footnotes"],
},
{
label: "vanilla",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/vanilla.git",
assetsRoot: "dist",
default: true,
supportedNoteTypes: ["footnotes"],
},
{
label: "atosh",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/atosh.git",
assetsRoot: "dist",
supportedNoteTypes: ["footnotes"],
},
{
label: "eclypse",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/eclypse.git",
assetsRoot: "dist",
supportedNoteTypes: ["footnotes"],
},
{
label: "logical",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/logical.git",
assetsRoot: "dist",
supportedNoteTypes: ["footnotes"],
},
{
label: "tenberg",
url: "https://gitlab.coko.foundation/coko-org/products/ketty/ketty-templates/tenberg.git",
assetsRoot: "dist",
supportedNoteTypes: ["footnotes"],
},
],
integrations: {
lulu: {
baseAPIURL: "https://api.sandbox.lulu.com/api/project-inject/projects",
redirectUri: "{clientUrl}/provider-redirect/lulu",
tokenUrl:
"https://api.sandbox.lulu.com/auth/realms/glasstree/protocol/openid-connect/token",
clientId: "{luluClientId}",
loginUrl:
"https://api.sandbox.lulu.com/auth/realms/glasstree/protocol/openid-connect/auth",
projectBaseUrl: "https://www.sandbox.lulu.com/account/projects",
},
},
};
Websockets
The server container exposes two different ports, one for the main server and one for the websocket server (used for keeping chapters locked when a user is editing). You should map each of these to a different port on your machine. See the server port part of the compose file for reference.
SSL
All containers will run on simple http or ws protocols, as they are meant to expose their ports only to the machine on which they are running. It is up to the specific sysadmin setup to map those exposed ports to a url that will have SSL certificates enabled (eg. via nginx reverse proxy or equivalent).